/*
 *  Copyright (c) 2009, Hugo Augusto Alves
 *  All rights reserved.
 * 
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *      * Neither the name of the Hugo Augusto Alves nor the
 *        names of its contributors may be used to endorse or promote products
 *        derived from this software without specific prior written permission.
 * 
 *  THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.liteml.parser;

/**
 *
 * @author Hugo
 */
public class LiteUtils {

    /** Targets of parser */
    public static enum Target {

        HTML,
        PLAIN
    }

    /** Types of text styles */
    public static enum Style {

        BOLD,
        ITALIC,
        UNDERLINE,
        STRIKE,
        SUPERSCRIPT,
        SUBSCRIPT
    }
    /** Title numbered char: '+' */
    public static final char CHAR_TITLE_N = '+';
    /** Title unnumbered char: '=' */
    public static final char CHAR_TITLE_U = '=';
    /** List numbered string: "# " */
    public static final String STR_LIST_N = "# ";
    /** List numbered string: "* " */
    public static final String STR_LIST_B = "* ";
    /** List numbered char: '#' */
    public static final char CHAR_LIST_N = '#';
    /** List bulleted char: '*' */
    public static final char CHAR_LIST_B = '*';
    /** Table char: '|' */
    public static final char CHAR_TABLE = '|';
    /** Table header char: '=' */
    public static final char CHAR_TABLE_HEADER = '=';
    /** Table label char: ':' */
    public static final char CHAR_TABLE_LABEL = ':';
    /** Table rowspan char: '^' */
    public static final char CHAR_TABLE_ROWSPAN = '^';
    /** Table colspan char: '>' */
    public static final char CHAR_TABLE_COLSPAN = '>';
    /** Table separator regex: "\\|" */
    public static final String TABLE_SEPARATOR_REGEX = "\\|";
    /** Table label cell string: "|:" */
    public static final String TABLE_LABEL_CELL = "|:";
    /** Horizontal rule start string: "----" */
    public static final String STR_HR = "----";
    /** Image begin string: "{{" */
    public static final String STR_BEGIN_IMAGE = "{{";
    /** Image end string: "}}" */
    public static final String STR_END_IMAGE = "}}";
    /** Image separator char: '|' */
    public static final char CHAR_SEPARATOR_IMAGE = '|';
    /** Line break char: '\\' */
    public static final char CHAR_LINE_BREAK = '\\';
    /** Comment char: '%' */
    public static final char CHAR_COMMENT = '%';
    /** Preformatted begin char: '%' */
    public static final char CHAR_BEGIN_PRE = '{';
    /** Preformatted end char: '%' */
    public static final char CHAR_END_PRE = '}';
    /** Preformatted begin string: "{{{" */
    public static final String STR_BEGIN_PRE = "{{{";
    /** Bold char: '*' */
    public static final char CHAR_BOLD = '*';
    /** Italic char: '/' */
    public static final char CHAR_ITALIC = '/';
    /** Underline char: '_' */
    public static final char CHAR_UNDERLINE = '_';
    /** Strike char: '-' */
    public static final char CHAR_STRIKE = '-';
    /** Superscript char: '^' */
    public static final char CHAR_SUPERSCRIPT = '^';
    /** Subscript char: '~' */
    public static final char CHAR_SUBSCRIPT = '~';
    /** Special string em dash: "- " */
    public static final String EM_DASH = "- ";
    /** Special string new line em dash: "\n- " */
    public static final String NL_EM_DASH = "- ";
    /** Html em dash: "&#8212; " */
    public static final String HTML_EM_DASH = "&#8212; ";
    /** Link begin string: "[[" */
    public static final String STR_BEGIN_LINK = "[[";
    /** Link end string: "]]" */
    public static final String STR_END_LINK = "]]";
    /** Link separator char: '|' */
    public static final char CHAR_SEPARATOR_LINK = '|';
    /** Link start char: '[' */
    public static final char CHAR_BEGIN_LINK = '[';
    /** Link end char: ']' */
    public static final char CHAR_END_LINK = ']';

    private static int bIndex = 0;
    private static int iIndex = 1;
    private static int uIndex = 2;
    private static int sIndex = 3;
    private static int spIndex = 4;
    private static int sbIndex = 5;
    private static boolean[] markers = new boolean[]{false, false, false, false, false, false};

    public static boolean isBreakLine(char c1, char c2) {
        return (c1 == CHAR_LINE_BREAK && c2 == CHAR_LINE_BREAK);
    }

    public static boolean isComment(char c1, char c2) {
        return (c1 == CHAR_COMMENT && c2 == CHAR_COMMENT);
    }

    public static boolean isPreformattedBegin(char c1, char c2, char c3) {
        return (c1 == CHAR_BEGIN_PRE && c2 == CHAR_BEGIN_PRE && c3 == CHAR_BEGIN_PRE);
    }

    public static boolean isPreformattedEnd(char c1, char c2, char c3) {
        return (c1 == CHAR_END_PRE && c2 == CHAR_END_PRE && c3 == CHAR_END_PRE);
    }

    public static Style isMarker(char c1, char c2) {
        if (c1 == CHAR_BOLD && c2 == CHAR_BOLD) {
            return Style.BOLD;
        }
        if (c1 == CHAR_ITALIC && c2 == CHAR_ITALIC) {
            return Style.ITALIC;
        }
        if (c1 == CHAR_UNDERLINE && c2 == CHAR_UNDERLINE) {
            return Style.UNDERLINE;
        }
        if (c1 == CHAR_STRIKE && c2 == CHAR_STRIKE) {
            return Style.STRIKE;
        }
        if (c1 == CHAR_SUPERSCRIPT && c2 == CHAR_SUPERSCRIPT) {
            return Style.SUPERSCRIPT;
        }
        if (c1 == CHAR_SUBSCRIPT && c2 == CHAR_SUBSCRIPT) {
            return Style.SUBSCRIPT;
        }
        return null;
    }

    public static boolean isLinkBegin(char c1, char c2) {
        return (c1 == CHAR_BEGIN_LINK && c2 == CHAR_BEGIN_LINK);
    }

    public static boolean isLinkEnd(char c1, char c2) {
        return (c1 == CHAR_END_LINK && c2 == CHAR_END_LINK);
    }

    public static boolean isHttpOrFtp(char c1, char c2, char c3) {
        if(c1 == 'h' && c2 == 't' && c3 == 't') return true;
        if(c1 == 'f' && c2 == 't' && c3 == 'p') return true;
        return false;
    }

    public static boolean isOpen(Style s) {
        switch (s) {
            case BOLD:
                return markers[bIndex];
            case ITALIC:
                return markers[iIndex];
            case UNDERLINE:
                return markers[uIndex];
            case STRIKE:
                return markers[sIndex];
            case SUPERSCRIPT:
                return markers[spIndex];
            case SUBSCRIPT:
                return markers[sbIndex];
            default:
                return false;
        }
    }

    /**
     *
     * @param s
     * @return true if was closed, false otherwise
     */
    public static boolean open(Style s) {
        if(isOpen(s)) return false;
        switch (s) {
            case BOLD:
                markers[bIndex] = true;
                break;
            case ITALIC:
                markers[iIndex] = true;
                break;
            case UNDERLINE:
                markers[uIndex] = true;
                break;
            case STRIKE:
                markers[sIndex] = true;
                break;
            case SUPERSCRIPT:
                markers[spIndex] = true;
                break;
            case SUBSCRIPT:
                markers[sbIndex] = true;
                break;
        }
        return true;
    }

    /**
     *
     * @param s
     * @return true if was opened, false otherwise
     */
    public static boolean close(Style s) {
        if(!isOpen(s)) return false;
        switch (s) {
            case BOLD:
                markers[bIndex] = false;
                break;
            case ITALIC:
                markers[iIndex] = false;
                break;
            case UNDERLINE:
                markers[uIndex] = false;
                break;
            case STRIKE:
                markers[sIndex] = false;
                break;
            case SUPERSCRIPT:
                markers[spIndex] = false;
                break;
            case SUBSCRIPT:
                markers[sbIndex] = false;
                break;
        }
        return true;
    }

    /**
     * close all markers
     */
    public static void closeAll() {
        for (int i = 0; i < markers.length; i++) {
            markers[i] = false;
        }
    }
}
